#include "characterclassmodel.h"


#include <characterclass.h>
#include <characterfeature.h>
#include <classlevel.h>
#include <skill.h>
#include <dtwentymodel.h>

#include <QMetaObject>
#include <QMetaEnum>
#include <QApplication>
#include <QFont>
#include <QColor>


namespace
{
QList<int> TITLE_METATYPE_ID_LIST;
int FEATURE_METATYPE_ID;
}


CharacterClassModel::CharacterClassModel(QObject *parent) :
    QSortFilterProxyModel(parent)
{
    TITLE_METATYPE_ID_LIST << qMetaTypeId<CharacterFeatures*>();
    TITLE_METATYPE_ID_LIST << qMetaTypeId<ClassLevels*>();
    TITLE_METATYPE_ID_LIST << qMetaTypeId<Skills*>();

    FEATURE_METATYPE_ID = qMetaTypeId<CharacterFeature*>();
}

QModelIndex CharacterClassModel::buddy(const QModelIndex &proxyIndex) const
{
    int itemTypeId = QSortFilterProxyModel::data(proxyIndex, DTwentyModel::Role_TYPE).toInt();
    if (itemTypeId != FEATURE_METATYPE_ID)
    {
        return QSortFilterProxyModel::buddy(proxyIndex);
    }

    return proxyIndex.sibling(proxyIndex.row(), 2); // value column
}

QVariant CharacterClassModel::data(const QModelIndex &proxyIndex, int role) const
{
    int itemTypeId = QSortFilterProxyModel::data(proxyIndex, DTwentyModel::Role_TYPE).toInt();


    switch (role)
    {
    case Qt::DisplayRole:
    {
        if (itemTypeId != FEATURE_METATYPE_ID)
        {
            break;
        }

        return featureData(proxyIndex, role);
    }

    case Qt::FontRole:
    {
        if (!TITLE_METATYPE_ID_LIST.contains(itemTypeId))
        {
            break;
        }
        QFont font = QApplication::font();
        font.setBold(true);
        if (proxyIndex.column() == 0)
        {
            font.setPixelSize(14);
        }
        return font;
    }

    case Qt::ForegroundRole:
    {
        if (!TITLE_METATYPE_ID_LIST.contains(itemTypeId))
        {
            break;
        }

        return QColor("white");
    }

    case Qt::BackgroundRole:
    {
        if (!TITLE_METATYPE_ID_LIST.contains(itemTypeId))
        {
            break;
        }
        return QColor("steelblue");
    }

    default:
        break;
    }

    return QSortFilterProxyModel::data(proxyIndex, role);
}

Qt::ItemFlags CharacterClassModel::flags(const QModelIndex &proxyIndex) const
{
    int itemTypeId = QSortFilterProxyModel::data(proxyIndex, DTwentyModel::Role_TYPE).toInt();
    if (itemTypeId != FEATURE_METATYPE_ID)
    {
        return QAbstractItemModel::flags(proxyIndex);
    }

    if (proxyIndex.column() != 2) // value column
    {
        return QAbstractItemModel::flags(proxyIndex);
    }

    return QAbstractItemModel::flags(proxyIndex) | Qt::ItemIsEditable;
}

bool CharacterClassModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    if (source_parent.data(DTwentyModel::Role_TYPE).toInt() == qMetaTypeId<ClassLevel*>())
    {
        return false;
    }

    return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}


QVariant CharacterClassModel::featureData(const QModelIndex &proxyIndex, int role) const
{
    if (role != Qt::DisplayRole)
    {
        return QSortFilterProxyModel::data(proxyIndex, role);
    }

    if (proxyIndex.column() == 3)
    {
        return QVariant();
    }

    if (proxyIndex.column() != 2)
    {
        return QSortFilterProxyModel::data(proxyIndex, role);
    }

    int offset = CharacterFeature::staticMetaObject.enumeratorOffset();
    int value = QSortFilterProxyModel::data(proxyIndex, role).toInt();

    switch (proxyIndex.row())
    {
    case 0:
        return CharacterFeature::staticMetaObject.enumerator(offset).valueToKey(value);

    case 1:
        return QString("%1 (%2)").arg(CharacterFeature::staticMetaObject.enumerator(offset+1).valueToKey(value)).arg(value);

    case 2:
        return CharacterFeature::staticMetaObject.enumerator(offset+2).valueToKey(value);

    case 3:
    case 4:
    case 5:
        return CharacterFeature::staticMetaObject.enumerator(offset+3).valueToKey(value);

    default:
        break;
    }

    return QSortFilterProxyModel::data(proxyIndex, role);
}

